<template>
  <div class="center_bottom">
    <Echart
      :options="options"
      id="bottomLeftChart"
      class="echarts_bottom"
      renderType="canvas"
    ></Echart>
  </div>
</template>

<script>
import { currentGET } from "api";
import { graphic } from "echarts";
import { itemColorArr } from "./pieColor";
export default {
  data() {
    return {
      options: {},
    };
  },
  props: {
    data: {
      type: Array,
      default: () => [],
    },
  },
  watch: {
    data: {
      handler(val) {
        this.init(val);
      },
      deep: true,
    },
  },
  mounted() {
    this.init(this.data);
  },
  methods: {
    getPie3D(pieData, internalDiameterRatio = 0.65) {
      // internalDiameterRatio:透明的空心占比
      const that = this;
      const series = [];
      let sumValue = 0;
      let startValue = 0;
      let endValue = 0;
      let legendData = [];
      let legendBfb = [];
      const k = 1 - internalDiameterRatio;
      //   pieData.sort((a, b) => {
      //     return b.value - a.value;
      //   });
      // 为每一个饼图数据，生成一个 series-surface 配置
      for (let i = 0; i < pieData.length; i++) {
        sumValue += pieData[i].value;
        const seriesItem = {
          name:
            typeof pieData[i].name === "undefined"
              ? `series${i}`
              : pieData[i].name,
          type: "surface",
          parametric: true,
          wireframe: {
            show: false,
          },
          pieData: pieData[i],
          pieStatus: {
            selected: false,
            hovered: false,
            k: k,
          },
          center: ["10%", "50%"],
          itemStyle: {
            opacity: 1,
            color: itemColorArr[i],
            fontSize: 16,
          },
        };

        // if (typeof pieData[i].itemStyle !== "undefined") {
        //   const itemStyle = {};
        //   typeof pieData[i].itemStyle.opacity !== "undefined"
        //     ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
        //     : null;
        //   seriesItem.itemStyle = itemStyle;
        // }

        //     seriesItem.light = {
        //   main: {
        //     intensity: 0, // 增强光照使渐变更明显
        //     shadow: true,
        //     shadowQuality: 'high',
        //     alpha: 55,
        //     beta: 10
        //   }
        // }
        series.push(seriesItem);
      }

      // 使用上一次遍历时，计算出的数据和 sumValue，调用 getParametricEquation 函数，
      // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation，也就是实现每一个扇形。
      legendData = [];
      legendBfb = [];
      for (let i = 0; i < series.length; i++) {
        endValue = startValue + series[i].pieData.value;
        series[i].pieData.startRatio = startValue / sumValue;
        series[i].pieData.endRatio = endValue / sumValue;
        series[i].parametricEquation = this.getParametricEquation(
          series[i].pieData.startRatio,
          series[i].pieData.endRatio,
          false,
          false,
          k,
          series[i].pieData.value
        );
        startValue = endValue;
        const bfb = that.fomatFloat(series[i].pieData.value / sumValue, 4);
        legendData.push({
          name: series[i].name,
          value: bfb,
        });
        legendBfb.push({
          name: series[i].name,
          value: bfb,
        });
      }
      // const boxHeight = this.getHeight3D(series, 26); // 通过传参设定3d饼/环的高度，26代表26px
      // console.log(boxHeight, "boxHeight");

      // 准备待返回的配置项，把准备好的 legendData、series 传入。
      // console.log(legendData, "legendData----");
      if (pieData.length) {
        series.push({
          type: "surface",
          parametric: true,
          background: "red",
          wireframe: { show: false },
          // itemStyle: {
          //   color: '#135593', // 底座颜色
          //   opacity: 0.8
          // },
          itemStyle: {
            // 动态颜色函数
            color: function (params) {
              const u = params.u;
              const v = params.v;
              // 顶部区域 (v接近-1)
              if (v > -0.3) return "white"; // 红色顶部
              // 外圈区域 (u在0-π/2和3π/2-2π范围)
              if (u < Math.PI / 2 || u > (3 * Math.PI) / 2) return "white"; // 绿色外圈
              // 默认区域
              return "#1665a7"; // 底座基础色
            },
            emphasis: {
              color: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.5,
                colorStops: [
                  { offset: 0, color: "#FFFFFF" },
                  { offset: 0.7, color: "#FF0000" },
                  { offset: 1, color: "#770000" },
                ],
              },
            },
            opacity: 0.9,
          },
          parametricEquation: {
            u: { min: 0, max: 2 * Math.PI, step: Math.PI / 20 },
            v: { min: -1, max: 0, step: 0.1 },
            x: function (u, v) {
              return Math.sin(u) * (1.4 + 0.5 * Math.cos(v));
            },
            y: function (u, v) {
              return Math.cos(u) * (1.4 + 0.5 * Math.cos(v));
            },
            z: function (u, v) {
              return -0.6; // 底座高度
            },
          },
        });
      }

      const option = {
        legend: {
          data: legendData,
          //   orient: "vertical",
          //   left: 34,
          right: 30,
          top: 30,
          //   bottom: 40,
          width: 220,
          padding: 15,
          itemGap: 15,
          itemWidth: 9,
          textStyle: {
            color: "#607FB5",
            fontSize: 9,
            textAlign: "left",
            // width: 8
          },
          show: true,
          icon: "circle",
          //   position: 'right',
        },
        labelLine: {
          show: true,
          lineStyle: {
            color: "#e5f8fe",
          },
        },
        label: {
          show: true,
          position: "inner",
          rich: {
            b: {
              color: "#e5f8fe",
              fontSize: 14,
              lineHeight: 20,
            },
            c: {
              fontSize: 16,
            },
          },
          formatter: (params) => {
            // console.log("params", params)
            return (
              params.data.name +
              Math.round(parseFloat(params.data.value)).toLocaleString()
            );
          },
        },
        tooltip: {
          formatter: (params) => {
            if (params.seriesName !== "mouseoutSeries") {
              return `${
                params.seriesName
              }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
                params.color
              };"></span>${Math.round(
                parseFloat(option.series[params.seriesIndex].pieData.value)
              ).toLocaleString()}`;
            }
          },
        },
        xAxis3D: {
          min: -1,
          max: 1,
        },
        yAxis3D: {
          min: -1,
          max: 1,
        },
        zAxis3D: {
          min: -1,
          max: 1,
        },
        grid3D: {
          show: false,
          boxHeight: 80, // 圆环的高度
          // boxHeight: 80 || boxHeight, // 圆环的高度
          top: 0,
          left: -160,
          viewControl: {
            // 3d效果可以放大、旋转等，请自己去查看官方配置
            alpha: 32, // 角度
            distance: 230, // 调整视角到主体的距离，类似调整zoom
            rotateSensitivity: 0, // 设置为0无法旋转
            zoomSensitivity: 0, // 设置为0无法缩放
            panSensitivity: 0, // 设置为0无法平移
            autoRotate: false, // 自动旋转
          },
        },
        series: series,
      };
      // console.log(option, "option----");

      return option;
    },

    // 获取3d图的最高扇区的高度
    // getHeight3D(series, height) {
    //   series.sort((a, b) => {
    //     return b.pieData.value - a.pieData.value;
    //   });
    //   return (height * 45) / series[0].pieData.value;
    // },

    // 生成扇形的曲面参数方程，用于 series-surface.parametricEquation
    getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
      // 计算
      const midRatio = (startRatio + endRatio) / 2;
      const startRadian = startRatio * Math.PI * 2;
      const endRadian = endRatio * Math.PI * 2;
      const midRadian = midRatio * Math.PI * 2;
      // 如果只有一个扇形，则不实现选中效果。
      if (startRatio === 0 && endRatio === 1) {
        isSelected = false;
      }
      // 通过扇形内径/外径的值，换算出辅助参数 k（默认值 1/3）
      k = typeof k !== "undefined" ? k : 1 / 3;
      // 计算选中效果分别在 x 轴、y 轴方向上的位移（未选中，则位移均为 0）
      const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
      const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
      // 计算高亮效果的放大比例（未高亮，则比例为 1）
      const hoverRate = isHovered ? 1.05 : 1;
      // 返回曲面参数方程
      return {
        u: {
          min: -Math.PI,
          max: Math.PI * 3,
          step: Math.PI / 32,
        },
        v: {
          min: 0,
          max: Math.PI * 2,
          step: Math.PI / 20,
        },
        x: function (u, v) {
          if (u < startRadian) {
            return (
              offsetX +
              Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
        },
        y: function (u, v) {
          if (u < startRadian) {
            return (
              offsetY +
              Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          if (u > endRadian) {
            return (
              offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
            );
          }
          return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
        },
        z: function (u, v) {
          if (u < -Math.PI * 0.5) {
            return Math.sin(u);
          }
          if (u > Math.PI * 2.5) {
            return Math.sin(u) * h * 0.1;
          }
          return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
        },
      };
    },

    fomatFloat(num, n) {
      var f = parseFloat(num);
      if (isNaN(f)) {
        return false;
      }
      f = Math.round(num * Math.pow(10, n)) / Math.pow(10, n); // n 幂
      var s = f.toString();
      var rs = s.indexOf(".");
      // 判定如果是整数，增加小数点再补0
      if (rs < 0) {
        rs = s.length;
        s += ".";
      }
      while (s.length <= rs + n) {
        s += "0";
      }
      return s;
    },
    init(newData) {
      // const LogisticsPieChartData = [
      //   {
      //     name: "故障原因故障原因134次",
      //     value: 310,
      //   },
      //   {
      //     name: "故障原因故障原因135次",
      //     value: 667,
      //   },
      //   {
      //     name: "故障原因故障原因136次",
      //     value: 1500,
      //   },
      //   {
      //     name: "故障原因故障原因137次",
      //     value: 1800,
      //   },
      //   {
      //     name: "故障原因故障原因138次",
      //     value: 178,
      //   },
      //   {
      //     name: "故障原因故障原因64次",
      //     value: 178,
      //   },
      // ];
      const ll = newData.map((item) => {
        return {
          name: item.failureReason + (item.reasonCout || 0) + "次",
          value: Number(item.reasonCout || 0),
        };
      });
      this.options = this.getPie3D(ll);
      //   this.options = {
      //     ...this.getPie3D(LogisticsPieChartData, 0.8),
      //     // legend: {
      //     //   top: "5%",
      //     //   left: "0%",
      //     //   orient: "vertical",
      //     //   formatter(params) {
      //     //     const item = LogisticsPieChartData.find(
      //     //       (ele) => ele.name === params
      //     //     );
      //     //     if (params === "pie2d") {
      //     //       return "";
      //     //     }
      //     //     return `${params} ${item && item.value}`;
      //     //   },
      //     //   textStyle: {
      //     //     color: "#fff",
      //     //   },
      //     // },
      //   };
    },
  },
};
</script>
<style lang="scss" scoped>
.center_bottom {
  width: 100%;
  height: 100%;

  .echarts_bottom {
    width: 100%;
    height: 100%;
  }
}
</style>
